package com.bert.generator.base;

import lombok.Data;

import java.util.*;

/**
 * 代码生成配置类
 */
@Data
public class GeneratorConfig {

    /**
     * 项目英文名称，如hikrmd，作为该项目的applicationName
     */
    private String projectName;

    /**
     * 项目版本号，如: 1.0.0
     */
    private String version;

    /**
     * 作者
     */
    private String author;

    /**
     * 数据库主机地址
     */
    private String dbHost;

    /**
     * 数据库端口
     */
    private Integer dbPort;

    /**
     * 数据库名称
     */
    private List<String> dbNames;

    /**
     * 数据库用户名
     */
    private String dbUserName;

    /**
     * 数据库连接密码
     */
    private String dbPwd;

    /**
     * 生成的根路径
     */
    private String generaPath;

    /**
     * 数据库表前缀以及该前缀对应的业务模块名称
     * 如数据库前缀为uc_ 对应的模块名称为portal，会生成hkbt-portal-xxx一系列完整的maven工程
     * 如果不配置默认会使用portal名称
     */
    private Map<String, String> prefixAndModuleName = new HashMap<>();

    /**
     * 模块包以及其对应的表名，本配置可以不填，建议区分
     * 如key是system value是[uc_dictionary,uc_dic_tree]，则两个表的生成基础类划分在module.system包下面
     * 如果不配置，则在module包下生成默认包名为business
     */
    private Map<String, List<String>> bizPackageName = new HashMap<>();

    /**
     * 不需要生成代码的表
     */
    private List<String> excludeTableNames = Arrays.asList("flyway_schema_history");

    /**
     * 只需要生成代码的表
     */
    private List<String> onlyNeedTableNames = new ArrayList<>();

    /**
     * 配置只需要生成代码的模块
     */
    private List<String> onlyNeedModules = new ArrayList<>();

    /**
     * 配置需要过滤的字段
     */
    private List<String> columnFilter = Arrays.asList("createBy", "createByName", "created", "createByIp", "ownerOrg", "dataValid", "global", "modifyBy", "modified", "modifyByName", "modifyByIp");

    public GeneratorConfig(String projectName, String dbUserName, String dbPwd, String dbHost, Integer dbPort, String generaPath, String... dbNames) {
        this.projectName = projectName;
        this.version = "1.0.0";
        this.author = "yanpl";
        this.dbUserName = dbUserName;
        this.dbPwd = dbPwd;
        this.dbHost = dbHost;
        this.dbPort = dbPort;
        this.generaPath = generaPath;
        this.dbNames = Arrays.asList(dbNames);
    }

    /**
     * 添加数据库前缀以及其对应的模块名称
     * 如数据表前缀为uc_的表对应的模块名称为portal，则uc_*表对应的所有类都会生成hkbt-portal-xxx工程中
     * 未找到前缀的表对应的类会自动创建到模块名为hkbt-portal-xxx的包内
     *
     * @param prefix
     * @param moduleName
     * @return
     */
    public GeneratorConfig addPrefix(String prefix, String moduleName) {
        prefixAndModuleName.put(prefix, moduleName);
        return this;
    }

    /**
     * 指定表所对应的业务包名称
     * 如：user  uc_user,uc_role，则这两张表生成的基础类在com.hkbt.portal.module."user"包内
     * 未找到的模块表会被生成为business的包内
     *
     * @param packageName
     * @param tableName
     * @return
     */
    public GeneratorConfig addBizPackageName(String packageName, String... tableName) {
        List<String> list = bizPackageName.getOrDefault(packageName, new ArrayList<>());
        list.addAll(Arrays.asList(tableName));
        bizPackageName.put(packageName, list);
        return this;
    }

    /**
     * 获取表名的前缀
     *
     * @param tableName
     * @return
     */
    public String getTablePrefix(String tableName) {
        for (Map.Entry<String, String> entry : prefixAndModuleName.entrySet()) {
            if (tableName.startsWith(entry.getKey())) {
                return entry.getKey();
            }
        }
        return "";
    }

    /**
     * 根据表名匹配对应的模块名称
     *
     * @param tableName
     * @return
     */
    public String matchModuleName(String tableName) {
        return prefixAndModuleName.getOrDefault(getTablePrefix(tableName), "portal");
    }

    /**
     * 根据表名匹配对应的包名
     *
     * @param tableName
     * @return
     */
    public String matchPackageName(String tableName) {
        Set<Map.Entry<String, List<String>>> entries = bizPackageName.entrySet();
        for (Map.Entry<String, List<String>> entry : entries) {
            if (entry.getValue().contains(tableName)) {
                return entry.getKey();
            }
        }
        return "business";
    }

    /**
     * 添加不需要生成代码的表
     *
     * @param excludeTableNames
     * @return
     */
    public GeneratorConfig addExcludeTableNames(String... excludeTableNames) {
        if (excludeTableNames != null && excludeTableNames.length > 0) {
            this.excludeTableNames.addAll(Arrays.asList(excludeTableNames));
        }
        return this;
    }

    /**
     * 添加只需要生成代码的表
     *
     * @param onlyNeedTableNames
     * @return
     */
    public GeneratorConfig addOnlyNeedTableNames(String... onlyNeedTableNames) {
        if (onlyNeedTableNames != null && onlyNeedTableNames.length > 0) {
            this.onlyNeedTableNames.addAll(Arrays.asList(onlyNeedTableNames));
        }
        return this;
    }

    /**
     * 添加只需要生成代码的表
     *
     * @param onlyNeedModules
     * @return
     */
    public GeneratorConfig addOnlyNeedModules(String... onlyNeedModules) {
        if (onlyNeedModules != null && onlyNeedModules.length > 0) {
            this.onlyNeedModules.addAll(Arrays.asList(onlyNeedModules));
        }
        return this;
    }

    /**
     * 配置需要过滤的字段
     *
     * @param columnFilter
     * @return
     */
    public GeneratorConfig columnFilter(String... columnFilter) {
        if (columnFilter != null && columnFilter.length > 0) {
            this.columnFilter.addAll(Arrays.asList(columnFilter));
        }
        return this;
    }

}
